package com.zhijian.medical.controller;

import com.zhijian.medical.annotation.Response;
import com.zhijian.medical.entity.po.ExperimentProcessSample;
import com.zhijian.medical.entity.vo.request.ExperimentProcessSampleSearchVo;
import com.zhijian.medical.entity.vo.response.ExperimentProcessSampleVo;
import com.zhijian.medical.entity.vo.response.ExperimentTypeEnumVo;
import com.zhijian.medical.enums.*;
import com.zhijian.medical.service.ExperimentProcessSampleService;
import com.zhijian.medical.util.AssertUtil;
import com.zhijian.medical.util.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 实验流程-样本管理 控制层
 *
 * @author HCG
 * @version 1.0
 * @date 2022-04-13 23:32:04
 */
@Slf4j
@Controller
@Api(tags = "实验流程-样本管理")
public class ExperimentProcessSampleController {

    @Autowired
    private ExperimentProcessSampleService service;

    /**
     * 新增
     *
     * @param param
     * @return
     */
    @Response
    @PostMapping("/experiment/process/sample")
    @ApiOperation("新增")
    public boolean insert(@RequestBody ExperimentProcessSample param) {
        log.info("{} - {}| insert info", this.getClass().getSimpleName(), param);
        return service.insert(param) != null;
    }

    /**
     * 新增
     *
     * @param param
     * @return
     */
    @Response
    @PostMapping("/experiment/process/sample/all")
    @ApiOperation("新增")
    public boolean insert(@RequestBody List<ExperimentProcessSample> param) {
        log.info("{} - {}| insert info", this.getClass().getSimpleName(), param);
        return service.insertAll(param);
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Response
    @DeleteMapping("/experiment/process/sample/{id}")
    @ApiOperation("删除")
    public boolean delete(@PathVariable("id") Long id) {
        log.info("{} - {}| delete info", this.getClass().getSimpleName(), id);
        service.deleteById(id);
        return true;
    }

    /**
     * 修改
     *
     * @param id
     * @param param
     * @return
     */
    @Response
    @PutMapping("/experiment/process/sample/{id}")
    @ApiOperation("修改")
    public boolean update(@PathVariable("id") Long id, @RequestBody ExperimentProcessSample param) {
        log.info("{} - {}| update info, {}", this.getClass().getSimpleName(), id, param);
        param.setId(id);
        return service.update(param);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @Response
    @GetMapping("/experiment/process/sample/{id}")
    @ApiOperation("根据id查询")
    public ExperimentProcessSampleVo selectById(@PathVariable("id") Long id) {
        log.info("{} - {}| query info", this.getClass().getSimpleName(), id);
        return service.selectVoById(id);
    }

    /**
     * 分页查询
     *
     * @param param
     * @return
     */
    @Response
    @PostMapping("/experiment/process/sample/page")
    @ApiOperation("分页查询")
    public Page<ExperimentProcessSampleVo> selectByCondition(@RequestBody(required = false) ExperimentProcessSampleSearchVo param) {
        if (param == null)
            param = ExperimentProcessSampleSearchVo.builder().build();
        log.info("{} - {}| query info", this.getClass().getSimpleName(), param);
        return service.selectPage(param);
    }

    /**
     * 查询荧光PCR实验待检测的样本列表
     *
     * @return
     */
    @Response
    @GetMapping("/experiment/process/sample/list/main/ygpcr")
    @ApiOperation("查询荧光PCR实验待检测的样本列表")
    public List<ExperimentProcessSampleVo> selectListByYgpcr() {
        return service.selectList(ExperimentProcessSampleSearchVo.builder()
                .mainType(ExperimentTypeEnum.PCR.getCode().byteValue())
                //只搜KNB的
                .projectList(ExperimentTypeEnum.PCR.getProject().subList(0, 3))
                .status(PcrSampleStatusEnum.YTQ.getCode().byteValue())
                .weatherQualified(ExperimentProcessSampleWeatherQualifiedEnum.HG.getCode().byteValue())
                .build());
    }

    /**
     * 查询荧光PCR实验待检测的样本列表
     *
     * @return
     */
    @Response
    @GetMapping("/experiment/process/sample/list/main/pcr/{type}")
    @ApiOperation("查询荧光PCR实验待检测的样本列表")
    public List<ExperimentProcessSampleVo> selectListByYgpcr(@ApiParam(name = "type", value = "1：KNB，2：高危HPV，3：JAK2，4：肺癌5种，5：PIK3CA，6：新冠病毒")
                                                             @PathVariable(value = "type", required = false) Byte type) {
        ExperimentProcessSampleSearchVo experimentProcessSampleSearchVo = ExperimentProcessSampleSearchVo.builder()
                .mainType(ExperimentTypeEnum.PCR.getCode().byteValue())
                .status(PcrSampleStatusEnum.YTQ.getCode().byteValue())
                .weatherQualified(ExperimentProcessSampleWeatherQualifiedEnum.HG.getCode().byteValue())
                .build();
        if (Objects.isNull(type)) {
            //默认KNB
            experimentProcessSampleSearchVo.setProjectList(ExperimentTypeEnum.PCR.getProject().subList(0, 3));
        } else {
            PcrTypeEnum pcrTypeEnum = PcrTypeEnum.getByCode(type.intValue());
            AssertUtil.notNull(pcrTypeEnum, "类型非法");
            assert pcrTypeEnum != null;
            switch (pcrTypeEnum) {
                case KNB:
                    experimentProcessSampleSearchVo.setProjectList(ExperimentTypeEnum.PCR.getProject().subList(0, 3));
                    break;
                case GW_HPV:
                    break;
                case FA_5:
                    break;
                case JAK2:
                    break;
                case PIK3CA:
                    break;
                case COV:
                    experimentProcessSampleSearchVo.setProject(ExperimentTypeEnum.PCR.getProject().get(7));
                    break;
                default:
                    experimentProcessSampleSearchVo.setProjectList(ExperimentTypeEnum.PCR.getProject().subList(0, 3));
                    break;
            }
        }
        return service.selectList(experimentProcessSampleSearchVo);
    }

    /**
     * 查询一代测序实验待检测的样本列表
     *
     * @return
     */
    @Response
    @GetMapping("/experiment/process/sample/list/main/ydcx")
    @ApiOperation("查询一代测序实验已核酸提取的样本列表")
    public List<ExperimentProcessSampleVo> selectListByYdcx() {
        return service.selectList(ExperimentProcessSampleSearchVo.builder()
                .mainType(ExperimentTypeEnum.SANGER.getCode().byteValue())
                .status(SangerSampleStatusEnum.YTQ.getCode().byteValue())
                .weatherQualified(ExperimentProcessSampleWeatherQualifiedEnum.HG.getCode().byteValue())
                .build());
    }

    /**
     * 查询二代测序实验待检测的样本列表
     *
     * @return
     */
    @Response
    @GetMapping("/experiment/process/sample/list/main/ngs")
    @ApiOperation("查询一代测序实验已核酸提取的样本列表")
    public List<ExperimentProcessSampleVo> selectListByNgs() {
        return service.selectList(ExperimentProcessSampleSearchVo.builder()
                .mainType(ExperimentTypeEnum.NGS.getCode().byteValue())
                .status(SangerSampleStatusEnum.YTQ.getCode().byteValue())
                .weatherQualified(ExperimentProcessSampleWeatherQualifiedEnum.HG.getCode().byteValue())
                .build());
    }

    /**
     * 查询某个实验相关的样本列表
     *
     * @param experimentProcessId
     * @return
     */
    @Response
    @GetMapping("/experiment/process/sample/list/p/{experimentProcessId}")
    @ApiOperation("查询某个实验相关的样本列表")
    public List<ExperimentProcessSampleVo> selectListByExperimentProcessId(@PathVariable("experimentProcessId") Long experimentProcessId) {
        return service.selectList(ExperimentProcessSampleSearchVo.builder()
                .experimentProcessId(experimentProcessId)
                .build());
    }

    /**
     * 修改备注
     *
     * @param id
     * @return
     */
    @Response
    @PutMapping("/experiment/process/sample/note/{id}")
    @ApiOperation("修改备注")
    public boolean update(@PathVariable("id") Long id,
                          @ApiParam(name = "note", value = "备注")
                          @RequestParam(value = "note") String note) {
        return service.updateNoteById(id, note);
    }

    /**
     * 获取最新的分子病理号
     *
     * @return
     */
    @Response
    @GetMapping("/experiment/process/sample/molecule/pathology/number")
    @ApiOperation("获取最新的分子病理号")
    public String createNextMoleculePathologyNumber() {
        return service.createNextMoleculePathologyNumber();
    }

    /**
     * 获取实验类型
     *
     * @return
     */
    @Response
    @GetMapping("/experiment/type/list")
    @ApiOperation("获取实验类型")
    public List<ExperimentTypeEnumVo> selectExperimentTypeEnums() {
        return service.selectExperimentTypeEnumVo();
    }

    /**
     * 根据实验类型获取项目
     *
     * @return
     */
    @Response
    @GetMapping("/experiment/process/sample/project/by/main/type/{mainType}")
    @ApiOperation("根据实验类型获取项目")
    public List<String> getProjectListByMainType(@PathVariable("mainType") Integer mainType) {
        ExperimentTypeEnum[] experimentTypeEnums = ExperimentTypeEnum.values();
        for (ExperimentTypeEnum experimentTypeEnum : experimentTypeEnums) {
            if (Objects.equals(mainType, experimentTypeEnum.getCode())) {
                return experimentTypeEnum.getProject();
            }
        }
        return Collections.emptyList();
    }

    /**
     * 获取样本类型列表
     *
     * @return
     */
    @Response
    @GetMapping("/experiment/sample/type/list")
    @ApiOperation("获取样本类型列表")
    public List<String> selectExperimentSampleTypeList() {
        ExperimentProcessSampleTypeEnum[] experimentProcessSampleTypeEnums = ExperimentProcessSampleTypeEnum.values();
        return Arrays.stream(experimentProcessSampleTypeEnums).map(ExperimentProcessSampleTypeEnum::getDesc).collect(Collectors.toList());
    }

    /**
     * 在实验里取消
     *
     * @param id
     * @return
     */
    @Response
    @DeleteMapping("/experiment/process/sample/cancel/{id}")
    @ApiOperation("在实验里取消")
    public boolean cancelInProcess(@PathVariable("id") Long id, @ApiParam(name = "cancelReason", value = "取消理由")
    @RequestParam(value = "cancelReason", required = true) String cancelReason,
                                   @ApiParam(name = "handleType", value = "处理方式，0：重新实验，1：退费")
                                   @RequestParam(value = "handleType", required = true) Byte handleType) {
        return service.cancelInProcess(id, cancelReason, handleType);
    }

}